package own.stu.jobgib.playown.netty.im.client.v2;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;

import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;

public class Client_v2 {

    public static final String HEART_BEAT = "heart beat!";

    private String host;
    private int port;
    private Bootstrap bootstrap;

    /** 重连策略 */
    private RetryPolicy retryPolicy;

    /**
     * 将<code>Channel</code>保存起来, 可用于在其他非handler的地方发送数据
     */
    private Channel channel;

    ThreadPoolExecutor executor;

    public Client_v2(String host, int port) {
        this(host, port, new ExponentialBackOffRetry(1000, Integer.MAX_VALUE, 60 * 1000));
    }
    public Client_v2(String host, int port, RetryPolicy retryPolicy) {
        this.host = host;
        this.port = port;
        this.retryPolicy = retryPolicy;
        init();
    }

    private void init() {
        executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(2);
        NioEventLoopGroup worker = new NioEventLoopGroup();
        bootstrap = new Bootstrap();
        bootstrap.group(worker)
                .channel(NioSocketChannel.class)
                .handler(new ClientHandlersInitializer(Client_v2.this));
    }

    public void connect() {
        synchronized (bootstrap) {
            ChannelFuture channelFuture = bootstrap.connect(host, port);
            channelFuture.addListener(getConnectionListener());
            channel = channelFuture.channel();
        }
        /*channel.closeFuture().addListener((res) -> {
            System.out.println(" ------ ");
            // executor.shutdown();

        });*/
    }

    private ChannelFutureListener getConnectionListener() {
        return new ChannelFutureListener() {
            @Override
            public void operationComplete(ChannelFuture future) throws Exception {
                if (!future.isSuccess()) {
                    System.out.println("ChannelFutureListener.future is fail");
                    future.channel().pipeline().fireChannelInactive();
                }
            }
        };
    }

    public RetryPolicy getRetryPolicy() {
        return retryPolicy;
    }

    public ThreadPoolExecutor getExecutor() {
        return executor;
    }

    public static void main(String[] args) {
        Client_v2 client = new Client_v2("127.0.0.1", 8899);
        client.connect();
    }
}
